package cn.huiyunche.base.service.interfaces.impl;

import cn.huiyunche.base.service.enums.BFeeModelEnum;
import cn.huiyunche.base.service.enums.BFeeTypeEnum;
import cn.huiyunche.base.service.interfaces.BFeeModelService;
import cn.huiyunche.base.service.interfaces.BFeeTypeService;
import cn.huiyunche.base.service.interfaces.SOrderFeeDetailService;
import cn.huiyunche.base.service.mappers.SOrderFeedetailMapper;
import cn.huiyunche.base.service.model.BFeeModel;
import cn.huiyunche.base.service.model.BFeeType;
import cn.huiyunche.base.service.model.SOrderFeedetail;
import cn.huiyunche.base.service.model.SOrderFeedetailExample;
import cn.huiyunche.base.service.vo.SOrderFeeDetailVo;
import cn.huiyunche.tools.basic.exceptions.BusinessException;
import org.apache.commons.collections4.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class SOrderFeeDetailServiceImpl implements SOrderFeeDetailService {

    private static final Logger logger = LoggerFactory.getLogger(SOrderFeeDetailServiceImpl.class);

    @Autowired
    private SOrderFeedetailMapper sOrderFeedetailMapper;

    @Autowired
    private BFeeModelService bFeeModelService;

    @Autowired
    private BFeeTypeService bFeeTypeService;

    @Override
    public SOrderFeedetail getFeeByOrder(Long id, int feeCode) {
        if (id == null || id == 0) {
            throw new BusinessException("订单id不能为空！");
        }

        if (feeCode == 0) {
            throw new BusinessException("费用code不能为空@");
        }

        SOrderFeedetailExample example = new SOrderFeedetailExample();
//		example.createCriteria().andOrderIdEqualTo(id).andFeeCodeEqualTo(feeCode);
        List<SOrderFeedetail> feeDetails = sOrderFeedetailMapper.selectByExample(example);
        if (CollectionUtils.isEmpty(feeDetails)) {
            throw new BusinessException("获取费用详情失败！");
        }
        return feeDetails.get(0);
    }

    @Override
    public List<SOrderFeedetail> getAllFeesByOrder(long orderId, int... feeCode) {
        if (0 == orderId) {
            logger.error("orderId must not be 0");
            throw new BusinessException("订单id不能为空！");
        }
        if (feeCode.length == 0) {
            throw new BusinessException("费用code不能为空！");
        }

        List<Integer> feeCodes = new ArrayList<>();
        for (int i = 0; i < feeCode.length; i++) {
            feeCodes.add(feeCode[i]);
        }
        SOrderFeedetailExample example = new SOrderFeedetailExample();
        example.setOrderByClause(" fee_code ASC ");
//		example.createCriteria().andOrderIdEqualTo(id).andFeeCodeIn(feeCodes);
        return sOrderFeedetailMapper.selectByExample(example);
    }

    @Override
    public long addFeeDetail(Long customerOrderId, Long feeTypeId, Integer feeCode, String feeName, BigDecimal price, BigDecimal actualAmount) {
        logger.info("addOrderFeeDetail params : {}，{}，{}, {}", customerOrderId, feeTypeId, feeName, price);
        if (null == customerOrderId) {
            logger.error("addOrderFeeDetail orderId must not be null");
            throw new BusinessException("订单id不能为空！");
        }
        if (null == feeTypeId) {
            logger.error("addOrderFeeDetail feeTypeId must not be null");
            throw new BusinessException("订单类型id不能为0");
        }
        if (null == feeName) {
            logger.error("addOrderFeeDetail feeName must not be null");
            throw new BusinessException("费用名称不能为空");
        }
        if (null == price) {
            logger.error("addOrderFeeDetail price must not be null");
            throw new BusinessException("金额不能为空！");
        }
        SOrderFeedetail feedetail = new SOrderFeedetail();
        feedetail.setOrderId(customerOrderId);
        feedetail.setFeeTypeId(feeTypeId);
        feedetail.setFeeCode(feeCode);
        feedetail.setFeeName(feeName);
        feedetail.setMoney(price);
        feedetail.setActualAmount(actualAmount);
        sOrderFeedetailMapper.insertSelective(feedetail);
        return feedetail.getId();
    }

    @Override
    public List<SOrderFeeDetailVo> getAllFeesBySOrder(long customerOrderId, Boolean isVeneer, Boolean hasContainsInvoiceFee) {
        logger.info("getAllFeesBySOrder param : {}", customerOrderId);
        if (0 == customerOrderId) {
            logger.error("getAllFeesBySOrder customerOrderId must not be 0");
            throw new IllegalArgumentException("客户订单id不能是0！");
        }

        if (null == hasContainsInvoiceFee) {
            hasContainsInvoiceFee = false;
        }

        BFeeModel feeModel = bFeeModelService.getByCode(BFeeModelEnum.INTERCITY_ORDER);
        if (isVeneer) {
            feeModel = bFeeModelService.getByCode(BFeeModelEnum.CITYWIDE_ORDER);
        }
        List<BFeeType> feeTypes = bFeeTypeService.getListByFeeModelId(feeModel.getId());

        SOrderFeedetailExample example = new SOrderFeedetailExample();
        example.createCriteria().andFeeTypeIdIn(feeTypes.stream().map(feeType -> feeType.getId()).collect(Collectors.toList())).andOrderIdEqualTo(customerOrderId);
        List<SOrderFeedetail> list = sOrderFeedetailMapper.selectByExample(example);
        if (CollectionUtils.isEmpty(list)) {
            logger.error("getAllFeesBySOrder list is empty");
            throw new BusinessException("获取客户订单费用详情失败！");
        }

        List<SOrderFeeDetailVo> fees = new ArrayList<>();
        BFeeType feeType;
        for (int i = 0; i < feeTypes.size(); i++) {
            feeType = feeTypes.get(i);
            long feeId = feeType.getId();

            SOrderFeeDetailVo vo = new SOrderFeeDetailVo();
            vo.setFeeCode(feeType.getFeeCode());
            vo.setFeeName(feeType.getFeeName());
            vo.setDiscount(feeType.getDiscount());
            fees.add(vo);
            list.stream().forEach(fee -> {
                if (fee.getFeeTypeId() == feeId) {
                    vo.setCost(fee.getMoney());
                    vo.setActualAmount(fee.getActualAmount());
                }
            });
        }

        if (!isVeneer) {
            if (!hasContainsInvoiceFee) {
                //运输费=运输费+发票税费
                long sum = fees.stream().filter(vo -> BFeeTypeEnum.SHIPPING.getValue() == vo.getFeeCode() || vo.getFeeCode() == BFeeTypeEnum.INVOICE_TAX.getValue()).mapToLong(vo -> (null == vo.getCost() ? 0 : vo.getCost()).longValue()).sum();
                fees.stream().filter(vo -> BFeeTypeEnum.SHIPPING.getValue() == vo.getFeeCode()).forEach(vo -> vo.setCost(BigDecimal.valueOf(sum)));

                long sumActual = fees.stream().filter(vo -> BFeeTypeEnum.SHIPPING.getValue() == vo.getFeeCode() || vo.getFeeCode() == BFeeTypeEnum.INVOICE_TAX.getValue()).mapToLong(vo -> (null == vo.getActualAmount() ? 0 : vo.getActualAmount()).longValue()).sum();
                fees.stream().filter(vo -> BFeeTypeEnum.SHIPPING.getValue() == vo.getFeeCode()).forEach(vo -> vo.setActualAmount(BigDecimal.valueOf(sumActual)));
                fees.remove(fees.stream().filter(fee -> BFeeTypeEnum.INVOICE_TAX.getValue() == fee.getFeeCode()).collect(Collectors.toList()).get(0));
            }
        }

        return fees;
    }

    @Override
    public void deleteByCOrderId(long customerOrderId) {
        logger.info("deleteByCOrderId param : {}", customerOrderId);
        if (0 == customerOrderId) {
            logger.error("deleteByCOrderId customerOrderId must not be 0");
            throw new IllegalArgumentException("客户订单id不能是0");
        }

        SOrderFeedetailExample example = new SOrderFeedetailExample();
        example.createCriteria().andOrderIdEqualTo(customerOrderId);
        sOrderFeedetailMapper.deleteByExample(example);
    }

}
